package com.dd.cloud.search.service;

import cn.easyes.core.biz.PageInfo;
import cn.easyes.core.conditions.LambdaEsQueryWrapper;
import com.dd.cloud.common.constants.PresConstants;
import com.dd.cloud.common.interceptor.UserInterceptor;
import com.dd.cloud.common.utils.ObjectUtils;
import com.dd.cloud.common.vo.LoginInfo;
import com.dd.cloud.search.contents.ESConstant;
import com.dd.cloud.search.entity.DrugsEs;
import com.dd.cloud.search.mapper.DrugsEsMapper;
import com.dd.cloud.user.req.pres.PresPageReq;
import com.dd.cloud.user.res.pres.DrugsModelInfoListRes;
import com.dd.cloud.user.res.pres.DrugsModelPageRes;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: 药品搜索es
 * @Author: czg
 * @Date: 2023/5/19 14:18
 * @Version: 1.0.0
 */
@Service
@Slf4j
public class DrugsEsServiceImpl implements DrugsEsService {
    @Autowired
    private DrugsEsMapper drugsEsMapper;

    /**
     * @param namesList:
     * @return Boolean
     * @description es保存药材列表数据
     * @author czg
     * @date 2023/5/19 14:24
     */
    @Override
    public Boolean esSave(List<DrugsModelPageRes> namesList) {
        //返回是否有错误, true有错误, false无错误
        boolean hasFail = false;
        if (namesList == null || namesList.isEmpty()) {
            return false;
        }
        List<DrugsEs> collect = namesList.stream().map(item -> {
            DrugsEs drugsEs = new DrugsEs();
            BeanUtils.copyProperties(item, drugsEs);
            return drugsEs;
        }).collect(Collectors.toList());
        try {
            drugsEsMapper.deleteIndex(ESConstant.DRUGS_INDEX);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Integer count = drugsEsMapper.insertBatch(collect);
        hasFail = count <= 0;
        log.info("药品数据上传是否有异常:{}", hasFail);
        return hasFail;
    }

    /**
     * @param req:
     * @return Page<DrugsModelPageRes>
     * @description es分页搜索药品
     * @author czg
     * @date 2023/5/20 13:59
     */
    @Override
    public PageInfo<DrugsEs> queryPage(PresPageReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();

        if (!StringUtils.isBlank(req.getStatus())) {
            req.setStatusStr(req.getStatus().split(","));
        }
        if (loginInfo.getType() == LoginInfo.UserType.PHAR) {
            req.setPharmacyId(loginInfo.getPharId());
        }
        LambdaEsQueryWrapper<DrugsEs> wrapper = new LambdaEsQueryWrapper();
        if (loginInfo.getType() == LoginInfo.UserType.PHAR) {
            req.setPharmacyId(loginInfo.getPharId());
        }
        if (req.getPharmacyId() != null) {
            wrapper.eq("pharId", req.getPharmacyId());
        }
        if (!StringUtils.isBlank(req.getKeyword())) {
            wrapper.and(i -> i.matchPhrase(DrugsEs::getHerbName, req.getKeyword(), 10f)
                    .or().matchPhrase(DrugsEs::getHerbNamePinyin, req.getKeyword(), 10f)
                    .or().matchPhrase(DrugsEs::getAlias, req.getKeyword(), 5f)
                    .or().matchPhrase(DrugsEs::getAliasPinyin, req.getKeyword(), 5f)
                    .or().matchPhrase(DrugsEs::getHerbNameTraditional, req.getKeyword(), 2f)
                    .or().matchPhrase(DrugsEs::getAliasTraditional, req.getKeyword(), 2f)
            );
        }
        wrapper.eq("status", PresConstants.ModelDrugsStatus.NOMER);
        PageInfo<DrugsEs> drugsEsPageInfo = drugsEsMapper.pageQuery(wrapper, req.getPage(), req.getPageSize());
        return drugsEsPageInfo;
    }

    /**
     * @param req:
     * @return int
     * @description 通过id更新药品, 如果es该id不存在, 则新增
     * @author czg
     * @date 2023/5/25 17:36
     */
    @Override
    public int updateDrugsById(DrugsModelPageRes req) {
        if (req.getId() == null) {
            return 0;
        }
        DrugsEs drugsEs = drugsEsMapper.selectById(req.getId());
        Integer integer = 0;
        if (drugsEs == null){
            drugsEs = new DrugsEs();
            //替换非空字段, 即只设置要改的值即可
            BeanUtils.copyProperties(req, drugsEs, ObjectUtils.getNullPropertyNames(req));
            integer = drugsEsMapper.insert(drugsEs);
        } else {
            BeanUtils.copyProperties(req, drugsEs, ObjectUtils.getNullPropertyNames(req));
            integer = drugsEsMapper.updateById(drugsEs);
        }

        return integer;
    }

    /**
     * @param id:
     * @return DrugsEs
     * @description 通过id查询药品
     * @author czg
     * @date 2023/5/26 10:16
     */
    @Override
    public DrugsEs getDrugsById(Integer id) {
        return drugsEsMapper.selectById(id);
    }

    /**
     * @param names:
     * @return Map<String, Object>
     * @description 通过药品名查询药品
     * @author czg
     * @date 2023/5/26 10:16
     */
    @Override
    public Map<String, Object> getDrugsByNames(String names, Integer pharId) {
        if (pharId == null) {
            pharId = 1;
        }
        Map<String, Object> maps = new HashMap<>();
        Map<String, List<DrugsEs>> map = new HashMap<>();
        if (StringUtils.isBlank(names)){
            return maps;
        }
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        String[] split = names.split(",");
        for (String name : split) {
            LambdaEsQueryWrapper<DrugsEs> wrapper = new LambdaEsQueryWrapper();
            wrapper.eq(DrugsEs::getPharId, pharId);
            wrapper.and(i -> i.matchPhrase(DrugsEs::getHerbName, name, 10f)
                    .or().matchPhrase(DrugsEs::getHerbNamePinyin, name, 10f)
                    .or().matchPhrase(DrugsEs::getAlias, name, 5f)
                    .or().matchPhrase(DrugsEs::getAliasPinyin, name, 5f)
                    .or().matchPhrase(DrugsEs::getHerbNameTraditional, name, 2f)
                    .or().matchPhrase(DrugsEs::getAliasTraditional, name, 2f)
            );
            List<DrugsEs> drugsEs = drugsEsMapper.selectList(wrapper);
            map.put(name, drugsEs);
        }
        maps.put("list", map);
        return maps;
    }

    /**
     * @description 删除es中指定id的药品
     * @param id:
     * @return int
     * @author czg
     * @date 2023/5/26 10:30
    */
    @Override
    public int delDrugsById(Integer id) {

        return drugsEsMapper.deleteById(id);
    }
}
